package com.example.lt.interceptor;

import com.example.lt.context.BaseContext;
import com.example.lt.entity.user.User;
import com.example.lt.service.user.UserService;
import com.example.lt.util.JwtUtil;
import com.example.lt.util.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author 小涛Tao
 * @Date: 2024/07/29/13:48
 * version 1.0 注释：自定义拦截器来校验前端传过来的token（jwt令牌）
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtTokenInterceptor implements HandlerInterceptor {

    private final UserService userService;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {

        if (request.getMethod().equals("OPTIONS")) {
            return true;
        }

        log.info("进行token校验");
        if (!JwtUtil.checkToken(request)) {
            response(Result.error().message("请登录后再操作"), response);
            return false;
        }

        final Long userId = JwtUtil.getUserId(request);
        final User user = userService.getById(userId); // 检查用户是否存在
        if (ObjectUtils.isEmpty(user)) {
            response(Result.error().message("用户不存在"), response);
            return false;
        }

        BaseContext.set(userId); // 把登录者 id 保存到 ThreadLocal 中
        return true;
    }

    private boolean response(Result result, HttpServletResponse response) throws IOException {
        // 设置 Access-Control-Allow-Origin 响应头，允许所有的跨域请求
        response.setHeader("Access-Control-Allow-Origin", "*");

        // 设置 Cache-Control 响应头，指示浏览器不要缓存该响应
        response.setHeader("Cache-Control", "no-cache");

        // 设置响应的字符编码为 UTF-8
        response.setCharacterEncoding("UTF-8");

        // 设置响应的内容类型为 application/json，告知客户端响应是一个 JSON 格式的对象
        response.setContentType("application/json");

        // 把 result 对象转换成JSON字符串，并写入响应中
        response.getWriter().println(objectMapper.writeValueAsString(result));
        response.getWriter().flush(); // 刷新 Writer，确保所有的数据都被写入到响应中
        return false;
    }

}
